package cn.com.bluemoon.daps.model.utils.factory.impl.field;

import cn.com.bluemoon.daps.common.enums.DatabaseType;
import cn.com.bluemoon.daps.common.sql.SqlScriptUtils;
import cn.com.bluemoon.daps.model.dto.SubordinateKeyDto;
import cn.com.bluemoon.daps.model.entity.DapDataModelTableField;
import cn.com.bluemoon.daps.model.utils.SqlUtils;
import cn.com.bluemoon.daps.model.utils.factory.FieldScriptFactory;
import cn.com.bluemoon.daps.model.utils.factory.constant.ScriptConstant;
import cn.com.bluemoon.daps.model.utils.factory.impl.key.AbsKeyScript;
import cn.com.bluemoon.daps.model.utils.factory.impl.key.MysqlKeyScript;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author karry
 * @Data 2021/9/7
 * @Time:10:34
 */
public abstract class AbsFieldScript implements FieldScriptFactory {

    /**
     * 生成mysql和pg字段的相同逻辑代码块
     * @return
     */
    public String createFieldPublicCode(List<DapDataModelTableField> fields, DatabaseType type){

        // 主键字段
        List<String> list = Lists.newArrayList();
        StringBuffer sqlBuffer = new StringBuffer();
        String single = type.equals(DatabaseType.MYSQL) ? "`" : "";
        for(DapDataModelTableField field : fields){
            createSingFieldScript(field, list, type, single, sqlBuffer);
        };
        // 主键
        if(!list.isEmpty() && type.equals(DatabaseType.MYSQL)){
            String collect = list.stream().collect(Collectors.joining(","));
            sqlBuffer.append(String.format("PRIMARY KEY (%s),", collect));
        }
        return sqlBuffer.toString();
    }

    public void createSingFieldScript(DapDataModelTableField field, List<String> list,
                                        DatabaseType type, String single, StringBuffer sqlBuffer){

        // 字段名、字段类型
        sqlBuffer.append(String.format("%s%s%s %s", single, field.getFieldName(), single, field.getDataType()));
        // 如果是mysql数据库，且为int类型的数据,不需要加上长度
        if(ScriptConstant.tinyList.contains(field.getDataType()) && type.equals(DatabaseType.MYSQL)){
            sqlBuffer.append(" ");
        }else {
            // 字段类型长度
            String dataLength = StringUtils.isBlank(field.getLength()) ? " " : String.format("(%s%s) ",field.getLength()
                    , SqlUtils.isNull(field.getDecimalLength()) ? "" : "," + field.getDecimalLength());
            sqlBuffer.append(dataLength);
        }
        // 是否为数值类型
        if(SqlUtils.isNumber(field.getDataType())){
            // 无符号
            String unSigned = SqlUtils.isNull(field.getUnSigned()) ? "" : "UNSIGNED ";
            // 填充零
            String zeroFill = SqlUtils.isNull(field.getZeroFill()) ? "" : "ZEROFILL ";
            sqlBuffer.append(unSigned).append(zeroFill);
        }
        // 主键
        if (!SqlUtils.isNull(field.getPrimaryKey()) && type.equals(DatabaseType.MYSQL)) {
            list.add(field.getFieldName()); sqlBuffer.append("NOT NULL ");
        }
        // 为空 1.是主键，not null 2.不是主键 default null
        if (SqlUtils.isNull(field.getNotNull())) {
            String defaultValue = StringUtils.isNotBlank(field.getDefaultValue()) ?
                    SqlUtils.getDefaultValue(field.getDataType(), field.getDefaultValue()) : "NULL";
            String isNull = SqlUtils.isNull(field.getPrimaryKey()) ? "DEFAULT " + defaultValue + " " : "";
            sqlBuffer.append(isNull);
        } else {
            // 非空 1.是主键，not null default '' 2.不是主键 not null default ''
            String isNull = SqlUtils.isNull(field.getPrimaryKey()) ||
                    type.equals(DatabaseType.PGSQL)? "NOT NULL " : "";
            String defaultValue = StringUtils.isNotBlank(field.getDefaultValue()) ?
                    String.format("DEFAULT %s ", SqlUtils.getDefaultValue(field.getDataType(), field.getDefaultValue())) : "";
            sqlBuffer.append(isNull).append(defaultValue);
        }
        // 是否自增
        String auto = SqlUtils.isNull(field.getAutoIncrement()) ? "" : "AUTO_INCREMENT ";
        String comment = SqlScriptUtils.formatComment(field.getComment());
        sqlBuffer.append(type.equals(DatabaseType.MYSQL) ? String.format("%sCOMMENT '%s',", auto, comment) : ",");
    }
}
